package com.mxx.common.data.jpa;

import javax.persistence.criteria.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.function.Function;

/**
 * @author itzgyw
 * @describe Jpa Specification条件构造工具
 */

public abstract class AbstractIgnoreNullSpecHelper<E extends AbstractIgnoreNullSpecHelper<E, K>, K> extends AbstractSpecHelper<E, K> {

    protected AbstractIgnoreNullSpecHelper(Root root, CriteriaBuilder criteriaBuilder, CriteriaQuery criteriaQuery) {
        super(root, criteriaBuilder, criteriaQuery);
    }

    public E equal(K key, Object val) {
        if (val == null) {
            return this.getTarget();
        }
        return super.equal(key, val);
    }

    public E equal(K key, Function<Path, Expression> function, Object val) {
        if (val == null) {
            return this.getTarget();
        }
        return super.equal(key, function, val);
    }

    public E notEqual(K key, Object val) {
        if (val == null) {
            return this.getTarget();
        }
        return super.notEqual(key, val);
    }

    public E leftLike(K key, String val) {
        if (val == null) {
            return this.getTarget();
        }
        return super.leftLike(key, val);
    }

    public E leftLike(K key, Function<Path, Expression> function, String val) {
        if (val == null) {
            return this.getTarget();
        }
        return super.leftLike(key, function, val);
    }

    public E notLeftLike(K key, String val) {
        if (val == null) {
            return this.getTarget();
        }
        return super.notLeftLike(key, val);
    }

    public E notLeftLike(K key, Function<Path, Expression> function, String val) {
        if (val == null) {
            return this.getTarget();
        }
        return super.notLeftLike(key, function, val);
    }

    public E rightLike(K key, String val) {
        if (val == null) {
            return this.getTarget();
        }
        return super.rightLike(key, val);
    }

    public E rightLike(K key, Function<Path, Expression> function, String val) {
        if (val == null) {
            return this.getTarget();
        }
        return super.rightLike(key, function, val);
    }

    public E notRightLike(K key, String val) {
        if (val == null) {
            return this.getTarget();
        }
        return super.notRightLike(key, val);
    }

    public E notRightLike(K key, Function<Path, Expression> function, String val) {
        if (val == null) {
            return this.getTarget();
        }
        return super.notRightLike(key, function, val);
    }

    public E like(K key, String val) {
        if (val == null) {
            return this.getTarget();
        }
        return super.like(key, val);
    }

    public E like(K key, Function<Path, Expression> function, String val) {
        if (val == null) {
            return this.getTarget();
        }
        return super.like(key, function, val);
    }

    public <T extends Comparable> E between(K key, T val, T val2) {
        if (val == null || val2 == null) {
            return this.getTarget();
        }
        return super.between(key, val, val2);
    }

    public E between(K key, String val, String val2) {
        if (val == null || val2 == null) {
            return this.getTarget();
        }
        return super.between(key, val, val2);
    }

    public E between(K key, Function<Path, Expression> function, String val, String val2) {
        if (val == null || val2 == null) {
            return this.getTarget();
        }
        return super.between(key, function, val, val2);
    }


    public <X extends Number> E ge(K key, X val) {
        if (val == null) {
            return this.getTarget();
        }
        return super.ge(key, val);
    }

    public <X extends Number> E gt(K key, X val) {
        if (val == null) {
            return this.getTarget();
        }
        predicateList.add(criteriaBuilder.gt(this.get(key), val));
        return super.gt(key, val);
    }

    public E greaterThan(K key, String val) {
        if (val == null) {
            return this.getTarget();
        }
        return super.greaterThan(key, val);
    }

    public E greaterThan(K key, Function<Path, Expression> function, String val) {
        if (val == null) {
            return this.getTarget();
        }
        return super.greaterThan(key, function, val);
    }

    public E greaterThanOrEqualTo(K key, String val) {
        if (val == null) {
            return this.getTarget();
        }
        return super.greaterThanOrEqualTo(key, val);
    }

    public E greaterThanOrEqualTo(K key, LocalDateTime val) {
        if (val == null) {
            return this.getTarget();
        }
        return super.greaterThanOrEqualTo(key, val);
    }

    public E greaterThanOrEqualTo(K key, LocalDate val) {
        predicateList.add(criteriaBuilder.greaterThanOrEqualTo(this.get(key), val));
        return this.getTarget();
    }

    public E greaterThanOrEqualTo(K key, Function<Path, Expression> function, String val) {
        if (val == null) {
            return this.getTarget();
        }
        return super.greaterThanOrEqualTo(key, function, val);
    }

    public <X extends Number> E le(K key, X val) {
        if (val == null) {
            return this.getTarget();
        }
        return super.le(key, val);
    }

    public <X extends Number> E lt(K key, X val) {
        if (val == null) {
            return this.getTarget();
        }
        predicateList.add(criteriaBuilder.lt(this.get(key), val));
        return super.lt(key, val);
    }

    public E lessThan(K key, String val) {
        if (val == null) {
            return this.getTarget();
        }
        return super.lessThan(key, val);
    }

    public E lessThan(K key, Function<Path, Expression> function, String val) {
        if (val == null) {
            return this.getTarget();
        }
        return super.lessThan(key, function, val);
    }

    public E lessThanOrEqualTo(K key, String val) {
        if (val == null) {
            return this.getTarget();
        }
        return super.lessThanOrEqualTo(key, val);
    }

    public E lessThanOrEqualTo(K key, Function<Path, Expression> function, String val) {
        if (val == null) {
            return this.getTarget();
        }
        return super.lessThanOrEqualTo(key, function, val);
    }

    public E lessThanOrEqualTo(K key, LocalDate val) {
        if (val == null) {
            return this.getTarget();
        }
        return super.lessThanOrEqualTo(key, val);
    }

    public E lessThanOrEqualTo(K key, LocalDateTime val) {
        if (val == null) {
            return this.getTarget();
        }
        return super.lessThanOrEqualTo(key, val);
    }

    public E in(K key, Collection collection) {
        if (collection == null || collection.isEmpty()) {
            return this.getTarget();
        }
        return super.in(key, collection);
    }

    public E notIn(K key, Collection collection) {
        if (collection == null || collection.isEmpty()) {
            return this.getTarget();
        }
        return super.notIn(key, collection);
    }

}
